class Turtle:

    def say(self):
        print("乌龟，爬爬爬")


class Cat:

    def say(self):
        print("小猫：喵喵喵")


class Dog:

    def say(self):
        print("小狗：汪汪汪")


# 花园中有乌龟，小猫，小狗
class Garden:
    tuple = Turtle()
    cat = Cat()
    dog = Dog()

    def say(self):
        self.tuple.say()
        self.cat.say()
        # 为什么要在前面加上 self 呢？
        # 如果不加呢？
        # dog.say()


garden = Garden()
garden.say()

# self 的作用：绑定，就是实例对象跟类的方法进行绑定，因为类的实例对象可以有千千万，并且方法是共享的，
# 我们在调用类的方法的时候，其实是在调用类的方法，并且把实例对象传递进去实现绑定
# 因为在类的实例中，除了方法是共享的，但是实例的属性是实例自己的，比如我们在给实例 a 添加一个属性的方法：a.x = 150 之后
# 实例 a 就有一个 x 属性，但是该类的其他实例 b 中就没有 x 属性


# 使用内省，我们通过 __dict__ 就能知道实例中有那些属性


garden_1 = Garden()
garden_2 = Garden()
# 我们给实例添加一个属性
garden_2.x = 520

print(garden_1.__dict__)  # {}
print(garden_2.__dict__)  # {'x': 520}
